import type { PtPage } from "./register";
import type { Page, PtComponentConst, Source } from "../types";
import { getRegisterComponent } from "./PtRegister";
import { PtData } from "./PtData";

/**
 * 资源分析
 */
export class PtPreload {
    private parent: PtPage;

    constructor(parentInstance: PtPage) {
        this.parent = parentInstance;
    }

    /**
     * 预加载资源
     */
    public async preloadSources(onChange?: (current: number, total: number) => void): Promise<void> {
        let current = 0;
        const list = this.getPreloadSources();

        if (list.length == 0) {
            return Promise.resolve();
        }

        for (let i = 0; i < list.length; i++) {
            const source = list[i];
            const img = await this.preload(source).catch(() => { });

            current = i + 1;

            if (img == null) {
                console.warn('图片加载失败', source)
            } else {
                onChange?.(current, list.length);
            }

            if (current >= list.length) {
                return Promise.resolve();
            }
        }
    }

    private getComponentPreloadSources(component: PtComponentConst, data: any): Source[] {
        const rc = getRegisterComponent(component.type)!;

        if (rc == null) {
            console.warn('没有注册组件：' + component.type);
            return [];
        }


        const preloadList = [];

        if ('getPreloadSource' in rc) {
            const sources = rc.getPreloadSource!(this.parent, component, new PtData(data, ''));
            preloadList.push(...sources);
        }

        return preloadList;
    }

    private getPreloadSources(): Source[] {
        const preloadList: Source[] = [];

        for (const page of this.parent.pages) {
            const rendereds = this.parent.getMatchBlobs(page);

            for (const data of rendereds) {
                for (const component of page.components) {
                    const sources = this.getComponentPreloadSources(component, data);
                    preloadList.push(...sources);
                }
            }

        }

        return preloadList;
    }

    private preload(source: Source) {
        // 异步加载资源
        return new Promise<HTMLImageElement | null>((resolve, reject) => {
            if (source.type == 'image') {
                const img = new Image();
                img.src = source.src;

                img.onload = () => {
                    resolve(img);
                };

                img.onerror = () => {
                    reject();
                };
            } else {
                resolve(null);
            }
        })
    }
}